package edu.gatech.cs2340.bytebankers.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;





import edu.gatech.cs2340.bytebankers.model.item.Item;


public class Wagon implements Serializable{

	private int itemWeight;
	private Map<Item, Integer> itemQuantity = new HashMap<Item, Integer>();
	public static int WEIGHT_CAPACITY = 2500;
	public static int MAX_OXEN_HEALTH = 10;
	private int oxenHealth = MAX_OXEN_HEALTH;
	
	
	/**
	 * Getter for current wagon weight
	 * @return Wagon's weight
	 */
	public int getItemWeight() {
		itemWeight = 0;
		Iterator it = itemQuantity.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry<Item, Integer> pair = (Map.Entry<Item, Integer>)it.next();
			if(!pair.getKey().getName().equals("Ox")) {
				itemWeight += (pair.getValue() * pair.getKey().getWeight());	
			}
		}
		
		
		return itemWeight;
	}
	
	public int getWeightCapacity() {
		return WEIGHT_CAPACITY;
	}
	
	public int getAvailableWeight() {
		return WEIGHT_CAPACITY - getItemWeight();
	}
	
	/**
	 * Getter for the quantity of ItemType the wagon contains.
	 * @param ItemType - Type of Item
	 * @return The quantity of ItemType
	 */
	public int getItemQuantityRemaining(Item item) {
		if(itemQuantity.containsKey(item)) {
			return itemQuantity.get(item);
		}
		
		return 0;

	}
	
	/**
	 * This method adds an amount of an item to the wagon.
	 * @param itemType The type of item
	 * @param amountAdded The number of items to add
	 */
	public void addItemQuantity(Item item, int amountAdded) {
		int oldQuantity = 0;
		
		if(itemQuantity.containsKey(item)){
			oldQuantity = itemQuantity.get(item);
		}
		itemQuantity.put(item, oldQuantity + amountAdded);
	}
	
	/**
	 * Getter for oxens' health
	 * @return Oxens' health
	 */
	public int getOxenHealth() {
		return oxenHealth;
	}
	
	/**
	 * This method will change the health of the oxen by a given amount
	 * @param amount The amount to alter by
	 */
	public void setOxenHealth(int amount) {
		this.oxenHealth = amount;
	}
	
	/**
	 * This method will use a given amount of a particular item
	 * @param itemType Type of the item being used
	 * @param amountUsed The number of items being used
	 * @return The amount left in the wagon of this item type.
	 */
	public int useItem(Item item, int amountUsed){
		
		int updatedQuantity = itemQuantity.get(item) - amountUsed;
		if (updatedQuantity < 0) {
			updatedQuantity = 0;
			itemQuantity.put(item, updatedQuantity);
			return -1;
		}
		itemQuantity.put(item, updatedQuantity);
		return updatedQuantity;
	}
	
	public List<Item> getListOfAvailableItems() {
		Iterator it = itemQuantity.entrySet().iterator();
		List<Item> availableItems = new ArrayList<Item>();
		while(it.hasNext()){
			Map.Entry<Item, Integer> pair = (Map.Entry<Item, Integer>)it.next();
			if(pair.getValue() > 0) {
				availableItems.add(pair.getKey());
			}
		}
		return availableItems;
	}
	
	/**
	 * This method returns the number of different types of items there are in the game. 
	 * @return Number of possible items
	 */
	public int getNumItemTypes() {
		return ItemType.values().length;
	}
}
